package com.ljx.rabbit.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ljx.rabbit.context.BaseContext;
import com.ljx.rabbit.domain.dto.ItemCommentDTO;
import com.ljx.rabbit.domain.dto.ItemCommentPage;
import com.ljx.rabbit.domain.po.*;
import com.ljx.rabbit.domain.vo.*;
import com.ljx.rabbit.mapper.CategoryMapper;
import com.ljx.rabbit.mapper.ItemMapper;
import com.ljx.rabbit.mapper.UserMapper;
import com.ljx.rabbit.service.IItemService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 商品 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-01-21
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class ItemServiceImpl extends ServiceImpl<ItemMapper, Item> implements IItemService {
    private final ItemMapper itemMapper;
    private final CategoryMapper categoryMapper;
    private final UserMapper userMapper;
    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public List<HeadGoods> getNewGoods(Integer limit) {
        List<Item> list = itemMapper.getNewGoods(limit);
        log.info("list:{}", list);
        List<HeadGoods> list1 = new ArrayList<>();
        if (list != null) {
            for (Item item : list) {
                HeadGoods goods = new HeadGoods();
                BeanUtils.copyProperties(item, goods);
                list1.add(goods);
            }
        }
        return list1;
    }

    @Override
    public ItemVo getDetail(Long id) {
        ItemVo itemVo = new ItemVo();
        Item item = getById(id);
        BeanUtils.copyProperties(item, itemVo);

        List<SkuVo> skuVos = itemMapper.getSkuVos(id);

        List<SpecsVo> specsVos = itemMapper.getSpecsVos(id);

        Brand brand = itemMapper.getBrand(id);

        List<String> mainPictures = itemMapper.getMainPictures(id);

        Category category = categoryMapper.selectById(item.getCategoryId());
        Categories categories0 = new Categories();
        BeanUtils.copyProperties(category, categories0);
        Categories categories1 = new Categories(category.getParentId(), category.getParentName(), 1, null);
        categories0.setParent(categories1);
        List<Categories> list = new ArrayList<>();
        list.add(categories0);
        list.add(categories1);

        Detail detail = new Detail().setPictures(mainPictures).setProperties(itemMapper.getProperties(id));

        for (int i = 1; i <= 2; i++) {
            Page<Item> page = new Page<>(i, 4);
            page(page);
            List<Item> records = page.getRecords();
            List<HeadGoods> headGoodsList = new ArrayList<>();
            for (Item record : records) {
                HeadGoods goods = new HeadGoods();
                BeanUtils.copyProperties(record, goods);
                headGoodsList.add(goods);
            }
            if (i == 1) {
                itemVo.setHotByDay(headGoodsList);
            } else {
                itemVo.setSimilarProducts(headGoodsList);
            }
        }

        Long sum = 0L;
        for (SkuVo vo : skuVos) {
            sum += vo.getInventory();
        }
        itemVo.setDetails(detail);
        itemVo.setCategories(list);
        itemVo.setMainPictures(mainPictures);
        itemVo.setBrand(brand);
        itemVo.setInventory(sum);
        itemVo.setSkus(skuVos);
        itemVo.setSpecs(specsVos);
        return itemVo;
    }

    @Override
    public List<HeadGoods> getHotGoods(Long id, Integer type, Integer limit) {//id是item的id
        Page<Item> page = new Page<>(type, limit);
        page(page);
        List<Item> records = page.getRecords();
        List<HeadGoods> headGoodsList = new ArrayList<>();
        for (Item record : records) {
            HeadGoods goods = new HeadGoods();
            BeanUtils.copyProperties(record, goods);
            headGoodsList.add(goods);
        }

        return headGoodsList;
    }

    @Override
    public List<HeadGoods> getRelevantGoods(Integer limit) {
        Page<Item> page = new Page<>(1, limit);
        List<Item> list = list(page);
        if (list != null && list.size() > 0) {
            List<HeadGoods> headGoodsList = new ArrayList<>();
            for (Item item : list) {
                HeadGoods goods = new HeadGoods();
                BeanUtils.copyProperties(item, goods);
                headGoodsList.add(goods);
            }
            return headGoodsList;
        }
        throw new RuntimeException("没有相关商品");
    }

    @Override
    public List<CommentVO> getComments(ItemCommentPage itemCommentDTO) {
        //1级评价
        List<CommentVO> commentVOList = new ArrayList<>();
        try {
            Criteria criteria = Criteria.where("itemId").is(itemCommentDTO.getId()).and("parentId").isNull();
            Query query = new Query(criteria);
            long count = mongoTemplate.count(query, Comment.class);
            updateById(new Item().setId(itemCommentDTO.getId()).setCommentCount((int) count));
            Integer type = itemCommentDTO.getType();
            if(type==2){
                query.with(Sort.by(Sort.Order.desc("createTime")))
                        .skip((itemCommentDTO.getPage() - 1) * itemCommentDTO.getPageSize())
                        .limit(itemCommentDTO.getPageSize());
            }else if(type==3){
                query.with(Sort.by(Sort.Order.desc("likenum")))
                        .skip((itemCommentDTO.getPage() - 1) * itemCommentDTO.getPageSize())
                        .limit(itemCommentDTO.getPageSize());
            }else if(type==4){
                query.with(Sort.by(Sort.Order.desc("replynum")))
                        .skip((itemCommentDTO.getPage() - 1) * itemCommentDTO.getPageSize())
                        .limit(itemCommentDTO.getPageSize());
            }else {
                query.with(Sort.by(
                        Sort.Order.desc("createTime"),
                        Sort.Order.desc("likenum"),
                        Sort.Order.desc("replynum")
                        ))
                        .skip((itemCommentDTO.getPage() - 1) * itemCommentDTO.getPageSize())
                        .limit(itemCommentDTO.getPageSize());
            }
            List<Comment> list = mongoTemplate.find(query, Comment.class);
            if (list != null && list.size() > 0) {
                for (Comment comment : list) {
                    //replynum
                    long replynum = mongoTemplate.count(Query.query(Criteria.where("parentId").is(comment.getId())), CommentChildren.class);
                    CommentVO commentVO = new CommentVO();
                    BeanUtils.copyProperties(comment, commentVO);
                    commentVO.setNickname(maskMiddleCharacters(comment.getNickname()));
                    commentVO.setReplynum(replynum);
                    commentVOList.add(commentVO);
                }
            }
        } catch (BeansException e) {
            throw new RuntimeException("获取1级评价失败");
        }
        return commentVOList;
    }

    @Override
    public Long likeCommentById(String commentId) {
        try {
            Query query1 = Query.query(Criteria.where("commentId").is(commentId).and("userId").is(BaseContext.getCurrentId()));
            if(mongoTemplate.exists(query1, "userlikes"))
                throw new RuntimeException("您已经点赞过了");
            mongoTemplate.save(new UserLikes().setCommentId(commentId).setUserId(BaseContext.getCurrentId()));

            Query query = Query.query(Criteria.where("_id").is(commentId));
            Update update = new Update();
            update.inc("likenum");
            mongoTemplate.updateFirst(query, update, "comment");
            return mongoTemplate.findOne(query, Comment.class).getLikenum();
        } catch (Exception e) {
            throw new RuntimeException("点赞失败,"+e.getMessage());
        }
    }

    @Override
    public void replyComment(ItemCommentDTO commentDTO) {
        //回复评论
        //1.父评论，replynum+1
        try {
            Query query = Query.query(Criteria.where("_id").is(commentDTO.getParentId()));
            Update update = new Update();
            update.inc("replynum");
            mongoTemplate.updateFirst(query, update, "comment");
        } catch (Exception e) {
            throw new RuntimeException("父评论，replynum+1错误");
        }
        //2.创建子评论
        try {
            Long userId = BaseContext.getCurrentId();
            User user = userMapper.selectById(userId);
            CommentChildren commentChildren = new CommentChildren();
            BeanUtils.copyProperties(commentDTO, commentChildren);
            commentChildren.setUserId(userId);
            commentChildren.setAvatar(user.getAvatar());
            commentChildren.setCreateTime(LocalDateTime.now());
            commentChildren.setNickname(user.getNickname());
            mongoTemplate.save(commentChildren);
        } catch (BeansException e) {
            throw new RuntimeException("创建子评论错误");
        }
    }

    @Override
    public List<CommentChildrenVO> getReplyComment(String commentId, Integer page, Integer pageSize) {
        //先看这个评论是否有子评论
        List<CommentChildrenVO> commentChildrenVOList = new ArrayList<>();
        Criteria criteria = Criteria.where("_id").is(commentId).and("replynum").gt(0);
        Query query = new Query(criteria);
        if (!mongoTemplate.exists(query, Comment.class)) {//无
            return commentChildrenVOList;
        }
        Comment comment = mongoTemplate.findOne(query, Comment.class);
        //有子评论
        Criteria criteria1 = Criteria.where("parentId").is(commentId);
        Query query1 = new Query(criteria1);
        query1.with(Sort.by(Sort.Order.desc("createTime")))
                .skip((page - 1) * pageSize)
                .limit(pageSize);
        List<CommentChildren> list = mongoTemplate.find(query1, CommentChildren.class);
        if (list == null || list.size() == 0) {
            return commentChildrenVOList;
        }
        for (CommentChildren commentChildren : list) {
            CommentChildrenVO commentChildrenVO = new CommentChildrenVO();
            BeanUtils.copyProperties(commentChildren, commentChildrenVO);
            commentChildrenVO.setNickname(maskMiddleCharacters(commentChildren.getNickname()));
            commentChildrenVO.setParentnickname(maskMiddleCharacters(comment.getNickname()));
            commentChildrenVOList.add(commentChildrenVO);
        }
        return commentChildrenVOList;
    }

    @Override
    public Long dislikeCommentById(String commentId) {
        try {
            Query query1 = Query.query(Criteria.where("commentId").is(commentId).and("userId").is(BaseContext.getCurrentId()));
            if(!mongoTemplate.exists(query1, "userlikes"))
                throw new RuntimeException("您未点赞");
            mongoTemplate.remove(query1, "userlikes");

            Query query = Query.query(Criteria.where("_id").is(commentId));
            Update update = new Update();
            update.inc("likenum", -1);
            mongoTemplate.updateFirst(query, update, "comment");
            return mongoTemplate.findOne(query, Comment.class).getLikenum();
        } catch (Exception e) {
            throw new RuntimeException("点赞失败"+e.getMessage());
        }
    }

    public static String maskMiddleCharacters(String input) {
        // 若输入字符串为 null ，直接返回 null
        if (input == null) {
            return null;
        }
        int length = input.length();
        // 若字符串长度小于等于 2 ，直接返回原字符串
        if (length <= 2) {
            return input;
        }
        // 提取首字符
        char firstChar = input.charAt(0);
        // 提取尾字符
        char lastChar = input.charAt(length - 1);
        // 构建中间的 4 个 * 字符串
        String maskedPart = "****";
        // 拼接首字符、中间的 * 和尾字符
        return firstChar + maskedPart + lastChar;
    }


}
